package vh.sphynx.runtime.impl;

import java.util.Map;

import vh.sphynx.runtime.ExecutionContext;
import vh.sphynx.runtime.IndexedMemberProvider;
import vh.sphynx.runtime.NamedMemberProvider;
import vh.sphynx.runtime.pattern.ITextLocator;
import vh.sphynx.util.PatternMismatchedException;
import vh.sphynx.util.SphynxRuntimeException;
import vh.sphynx.util.SphynxTypeMismatchException;

public abstract class AbstractTextLocator implements ITextLocator, IndexedMemberProvider, NamedMemberProvider {
	
	protected ExecutionContext context;
	protected Map<String, Integer> fields;
	
	public abstract boolean isMatched();
	
	@Override
	public boolean isWritable() {
		return false;
	}
	
	@Override
	public boolean isInitialized() {
		return isMatched();
	}
	
	public void setMember(String fieldname, Object value) {
		throw new UnsupportedOperationException();
	}

	public Object getMember(String fieldname) {
		if (!isMatched())
			throw new SphynxRuntimeException(context, null, "Location is not matched or not jet initialized");
		
		if (fields != null && fields.containsKey(fieldname)) {
			int idx = (Integer) fields.get(fieldname);
			if (idx >= 0)
				return basicGetMember(idx);
		}
		return null;
	}

	public void setMember(Object value, Object... indecies) {
		throw new UnsupportedOperationException();
	}

	public Object getMember(Object...indecies) {
		if (indecies.length != 1)
			throw new SphynxRuntimeException(context, null, "Multiple indecies are not supported" );
		if (!isMatched())
			throw new PatternMismatchedException(context, null, "Location is not matched or not jet initialized");
		if (indecies[0] instanceof Integer) {
			Integer idx = (Integer)indecies[0];
			return basicGetMember(idx);
		}
		if (indecies[0] instanceof String)
			return getMember((String)indecies[0]);
		throw new SphynxTypeMismatchException(context, null, Integer.class, indecies[0]);
	}
	
	protected abstract Object basicGetMember(int idx);

	public abstract int locate(CharSequence input, int sidx, String pattern, int patternFlag, int operator, boolean lastPostOnUnmatch, Map<String, Integer> groups);

	public AbstractTextLocator() {
		super();
	}

	public void setContext(ExecutionContext context) {
		this.context = context;
	}

	public ExecutionContext getContext() {
		return context;
	}

}